home *** CD-ROM | disk | FTP | other *** search
- #include <stdio.h>
- #include <signal.h>
- #include <setjmp.h>
- #include <stream.h>
- #include <string.h>
- #include "chbuffer.hxx"
- #include "daims.hxx"
- /*
- **
- ** Routines to do the commands in yyparse.y
- */
-
- extern int yyparse();
-
- char * progname; /* for error messages */
- char * source_name; /* current source file name */
- int lineno; /* to say where they occurred */
- jmp_buf begin; /* place to return to on error */
- extern int ydebug_f;
- extern int ldebug_f;
- int debug_f;
- int trace_f;
- int sstep_f;
-
- void error(char *s, char * s2)
- {
- cerr << s << " " << s2 << "\n";
- exit(1);
- }
-
- void prompt()
- {
- cout << "DAIMS> ";
- cout.flush();
- }
-
- /*
- -*++ help(): get help inside the DAIMS interpreter
- **
- ** (*++ history:
- ** 7 Dec 87 Bruce Eckel Creation date
- ** ++*)
- **
- ** (*++ detailed: The help file contains a general message (printed when
- ** "help" is typed by itself) followed by specific messages. Each specific
- ** message begins with the subject name(s) surrounded by curly braces. If a
- ** name within the curly braces is matched, the following text is printed out,
- ** until the next '{'
- ** ++*)
- */
-
- void help(char * subject)
- {
- char ch;
- char stg[80];
- int NOT_FOUND = 1;
- filebuf helpfile;
- if (helpfile.open(HELP_FILE,input) == 0)
- error("cannot open help file",HELP_FILE);
- istream help(&helpfile);
- if (debug_f) cerr << "subject `" << (int)subject << "'\n";
- if(subject) {
- if (debug_f) cerr << "looking for a subject: " << subject << "\n";
- /* find the subject */
- while (NOT_FOUND) {
- while(help.get(ch)) {
- if (debug_f) cerr.put(ch);
- if (ch == '{') break; /* subject names in "{}" */
- }
- if (debug_f) cerr << "found left brace\n";
- if (help.eof()) {
- cerr << "subject \"" << subject << "\" not found\n";
- return;
- }
- do {
- help >> stg; /* this is a nifty feature */
- if (debug_f) cerr << "checking : " << stg << "\n";
- NOT_FOUND = strcmp(stg,subject); /* zero if equal */
- if(!NOT_FOUND) break;
- if (debug_f) cerr << "NOT_FOUND = " << NOT_FOUND << "\n";
- } while (*stg != '}');
- if (debug_f) if (*stg == '}') cerr << " found right brace\n";
- }
- while(help.get(ch))
- if (ch == '}') break; /* find the other "subject" brace */
- if (debug_f) cerr << "dumping subject text:\n";
- while(help.get(ch)) {
- if (ch == '{') break;
- cout.put(ch); /* dump the subject text */
- }
- }
- else {
- if (debug_f) cerr << "subject help";
- while(help.get(ch)) {
- if (ch == '{') break;
- cout.put(ch); /* dump the help subjects */
- }
- }
- cout << "\n";
- }
-
-
- /*
- -*++ source(): get input from a new file, saving the old environment
- **
- ** (*++ history:
- ** 7 Dec 87 Bruce Eckel Creation date
- ** ++*)
- **
- ** (*++ detailed: You can source files to any level, since the current
- ** environment is saved on the stack and restored when the end of the sourced
- ** file is encountered.
- ** ++*)
- */
-
- void source(char * filename)
- {
- char dummy[10];
- int tmp_lineno = lineno; /* save current line count */
- filebuf sourcefile;
- istream tmpcin(cin); /* to hold cin while sourcing */
- char * oldname = source_name; /* remember what file called us */
- source_name = filename; /* source_name is global */
- if (sourcefile.open(filename,input) == 0)
- error("cannot open input file",filename);
- istream source(&sourcefile);
- cin = source;
- lineno = 1; /* start counting lines in the new file */
- if(oldname && trace_f) { /* if this file was called from another file */
- cout << "trace: open new source file:\n ";
- buf.dump();
- cout << "\n";
- }
- else if (trace_f) buf.erase();
- while(yyparse()) { /* parse the sourced file */
- lineno++;
- if(trace_f) { /* if tracing and sourcing a file, echo */
- cout << "trace: previous output generated by line " << lineno -1;
- cout << " in sourced file " << "\"" << source_name << "\"" << ":\n ";
- buf.dump();
- }
- if (sstep_f) { cout << "press RET to continue "; gets(dummy); }
- }
- cin = tmpcin; /* reset the input */
- sourcefile.close();
- lineno = tmp_lineno; /* reset line number counting */
- source_name = oldname; /* so the error messages work right */
- }
-
-
- /*
- -*++ option(): parses command line options
- **
- ** (*++ history:
- ** 7 Dec 87 Bruce Eckel Creation date
- ** ++*)
- **
- ** (*++ detailed:
- ** ++*)
- */
-
- int option(char * opt)
- {
- /* Returns true if more options may be in the string */
-
- switch (*opt) {
- case 'y': /* Yacc debug flag */
- ydebug_f = 1;
- return(1);
- case 'l': /* Lex debug flag */
- ldebug_f = 1;
- return(1);
- case 'd': /* general debug flag */
- debug_f = 1;
- return(1);
- case 't': /* source file trace flag */
- trace_f = 1;
- return(1);
- case 's': /* source file single-step flag */
- sstep_f = 1;
- return(1);
- case '\0': /* End of string */
- return(0);
- default:
- printf("%s: bad option (%c)\n",*opt);
- break;
- }
- return(0);
- }
-
- void warning (char * s, char * t)
- {
- cerr << progname << ": " << s;
- if (t) cerr << " " << t;
- if (source_name)
- cerr << " near line " << lineno << " in sourced file: " << source_name;
- cerr << "\n";
- }
-
-
- void execerror(char * s, char * t)
- {
- warning(s,t);
- longjmp(begin,0);
- }
-
- SIG_PF fpecatch() /* catch floating-point exceptions */
- {
- execerror("floating point exceptions", (char *)0 );
- return (SIG_PF)0;
- }
-
-
- /*
- -*++ main(): The main interpreter loop for daims
- **
- ** (*++ history:
- ** 7 Dec 87 Bruce Eckel Creation date
- ** ++*)
- **
- ** (*++ detailed: Sets up to catch control-C's, Floating-point exceptions (not
- ** functional yet) parses the command line switches and starts sourcing a file
- ** if one was requested on the command line.
- ** ++*)
- */
-
- main(int argc, char *argv[])
- {
- progname = argv[0];
- int yreturn;
- char * opt;
- char **av = argv;
- int ac = argc;
- debug_f = ydebug_f = ldebug_f = 0;
-
- /* Parse the command line */
- while (--ac > 0 && (*++av)[0] == '-') {
- for (opt = av[0]+1; option(opt); opt++)
- ;
- cout << "option " << av[0] << "\n";
- }
-
- if (argc > 1 && (*av)[0] != '-') { source(av[0]); }
- cout << "type \"help\" for help\n";
- setjmp(begin);
- // signal(SIGFPE, fpecatch);
-
-
- do {
- prompt();
- if(debug_f) cerr << "entering yyparse()\n";
- yreturn = yyparse();
- if (trace_f) buf.erase();
- if(debug_f) cerr << "leaving yyparse()\n";
- if (debug_f) cerr << " yyparse returned " << yreturn << "\n";
- } while (yreturn);
- }